<template>
  <div>
    <div style="margin-bottom: 10px">
      <el-button type="danger" @click="removeAllPoint">删除所有点标记</el-button>
      <el-input v-model="form.lon" placeholder="经度" style="margin-left: 10px;width: 200px"></el-input>
      <el-input v-model="form.lat" placeholder="纬度" style="margin-left: 10px;width: 200px"></el-input>
      <el-button type="success" @click="addPoints" style="margin-left: 10px">新增</el-button>
      <el-button type="warning" @click="removePoint" style="margin-left: 10px">删除</el-button>
    </div>
    <div id="map-container"></div>
  </div>

</template>
<script>
import { Map, View,Feature } from 'ol'
import { Tile as TileLayer } from 'ol/layer'
import { get } from 'ol/proj';
import { getWidth, getTopLeft } from 'ol/extent'
import { WMTS } from 'ol/source'
import WMTSTileGrid from 'ol/tilegrid/WMTS'
import { defaults as defaultControls} from 'ol/control';
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import {Point} from "ol/geom";
import {Icon, Style} from "ol/style";

export const projection = get("EPSG:4326");
const projectionExtent = projection.getExtent();
const size = getWidth(projectionExtent) / 256;
const resolutions = [];
for (let z = 0; z < 19; ++z) {
  resolutions[z] = size / Math.pow(2, z);
}

export default {
  data() {
    return {
      map:null,
      //所有点信息都放在这个图层
      pointLayer: new VectorLayer({
        source: new VectorSource(),
      }),
      form:{
        lon:'',
        lat:'',
      },
    }
  },
  mounted(){
    this.initMap() // 加载矢量底图
  },
  methods:{
    initMap() {
      const KEY = '你申请的KEY'
      this.map = new Map({
        target: 'map-container',
        layers: [
          // 底图
          new TileLayer({
            source: new WMTS({
              url: `http://t{0-6}.tianditu.com/vec_c/wmts?tk=${KEY}`,
              layer: 'vec', // 矢量底图
              matrixSet: 'c', // c: 经纬度投影 w: 球面墨卡托投影
              style: "default",
              crossOrigin: 'anonymous', // 解决跨域问题 如无该需求可不添加
              format: "tiles", //请求的图层格式，这里指定为瓦片格式
              wrapX: true, // 允许地图在 X 方向重复（环绕）
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions: resolutions,
                matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
              })
            })
          }),
          // 标注
          new TileLayer({
            source: new WMTS({
              url: `http://t{0-6}.tianditu.com/cva_c/wmts?tk=${KEY}`,
              layer: 'cva', //矢量注记
              matrixSet: 'c',
              style: "default",
              crossOrigin: 'anonymous',
              format: "tiles",
              wrapX: true,
              tileGrid: new WMTSTileGrid({
                origin: getTopLeft(projectionExtent),
                resolutions: resolutions,
                matrixIds: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15','16','17','18']
              })
            })
          })
        ],
        view: new View({
          center: [118.958366,32.119577],
          projection: projection,
          zoom: 12,
          maxZoom: 17,
          minZoom: 1
        }),
        //加载控件到地图容器中
        controls: defaultControls({
          zoom: false,
          rotate: false,
          attribution: false
        })
      })
      //把图层添加到地图上
      this.map.addLayer(this.pointLayer);
      //标记点初始化点击事件
      this.initPointEvent();
    },
    /**
     * 根据经纬度坐标添加自定义图标 支持base64
     */
    addPoints() {
      let coordinate = [this.form.lon,this.form.lat];
      // 创建feature要素，一个feature就是一个点坐标信息
      let feature = new Feature({
        geometry: new Point(coordinate),
      });
      // 设置要素的图标
      feature.setStyle(
          new Style({
            // 设置图片效果
            image: new Icon({
              src: 'http://api.tianditu.gov.cn/img/map/markerA.png',
              // anchor: [0.5, 0.5],
              scale: 1,
            }),
          }),
      );

      // 要素添加到地图图层上
      this.pointLayer.getSource().addFeature(feature);
      // 设置中心
      this.map.getView().setCenter(coordinate);
    },
    removePoint() {
      let coordinate = [this.form.lon,this.form.lat];
      // 从图层源中获取当前要素
      const features = this.pointLayer.getSource().getFeatures();
      let _that = this;
      // 遍历要素，查找匹配的坐标
      features.forEach(feature => {
        const geometry = feature.getGeometry();
        const featureCoordinates = geometry.getCoordinates();
        // 检查经纬度是否匹配
        if (featureCoordinates[0] == coordinate[0] && featureCoordinates[1] == coordinate[1]) {
          // 找到匹配的要素，移除它
          _that.pointLayer.getSource().removeFeature(feature);
        }
      });
    },
    removeAllPoint(){
      // 从图层源中获取当前要素
      const features = this.pointLayer.getSource().getFeatures();
      // 遍历要素
      features.forEach(feature => {
        this.pointLayer.getSource().removeFeature(feature);
      });
    },
    initPointEvent(){
      //给点初始化点击事件
      this.map.on("singleclick", (e) => {
        let pixel = this.map.getEventPixel(e.originalEvent);
        let feature = this.map.forEachFeatureAtPixel(pixel, function(feature) { return feature; });
        let coordinate = e.coordinate;
        if(feature){
          console.log("当前点击经纬度："+coordinate);
        }
      });
    }
  }
}
</script>
<style scoped>
#map-container {
  width: 100%;
  height: 100vh;
}
</style>
